

static void run_flash_device_id_test(void)
{
	uint32_t ul_rc;
	uint32_t unique_id[4];

	/* Read flash device id */
	ul_rc = flash_read_unique_id(unique_id, 4);

	/* Validate the get flash device id function */
	debug_print("flash device id: %x,%x,%x,%x\r\n",unique_id[0],unique_id[1],unique_id[2],unique_id[3]);
}

static void run_flash_configure_test()
{
	uint32_t ul_default_ws;
	uint32_t ul_tmp_ws;
	uint32_t ul_mck = sysclk_get_cpu_hz();

	/* Backup default wait state */
	ul_default_ws = flash_get_wait_state(IFLASH_ADDR);

	/* Check the flash init function */
	flash_init(FLASH_ACCESS_MODE_128, 6);

	/* Get the wait state set by flash_init */
	ul_tmp_ws = flash_get_wait_state(IFLASH_ADDR);
	
	/* Validate the flash initialization function */
	debug_print("Test flash configure:%d\r\n",ul_tmp_ws);

	/* Set the new wait state */
	flash_set_wait_state(IFLASH_ADDR, ul_default_ws+1);
	
	/* Get the wait state */
	ul_tmp_ws =  flash_get_wait_state(IFLASH_ADDR);

	/* Validate the set flash wait state function */
	debug_print("Test flash configure:%d\r\n",ul_tmp_ws);

	/* Adaptively set the wait state */
	flash_set_wait_state_adaptively(IFLASH_ADDR);

	/* Validate the adaptively set wait state function, get the wait state and
	 * check with the default>
	 */
	if (ul_mck < CHIP_FREQ_FWS_0) {
		ul_tmp_ws =  flash_get_wait_state(IFLASH_ADDR);
		debug_print("Test flash configure:adaptively set wait state:%d\r\n",ul_tmp_ws);
	} else if (ul_mck < CHIP_FREQ_FWS_1) {
		ul_tmp_ws =  flash_get_wait_state(IFLASH_ADDR);
		debug_print("Test flash configure:adaptively set wait state:%d\r\n",ul_tmp_ws);
	} else if (ul_mck < CHIP_FREQ_FWS_2) {
		ul_tmp_ws =  flash_get_wait_state(IFLASH_ADDR);
		debug_print("Test flash configure:adaptively set wait state:%d\r\n",ul_tmp_ws);
#if (SAM3XA || SAM3U)
	} else if (ul_mck < CHIP_FREQ_FWS_3) {
		ul_tmp_ws =  flash_get_wait_state(IFLASH_ADDR);
		debug_print("Test flash configure:adaptively set wait state:%d\r\n",ul_tmp_ws);
	} else {
		ul_tmp_ws =  flash_get_wait_state(IFLASH_ADDR);
		debug_print("Test flash configure:adaptively set wait state:%d\r\n",ul_tmp_ws);
	}
#else
	} else {
		ul_tmp_ws =  flash_get_wait_state(IFLASH_ADDR);
		debug_print("Test flash configure:adaptively set wait state:%d\r\n",ul_tmp_ws);
	}
#endif

	/*Restore default wait state */
	flash_set_wait_state(IFLASH_ADDR, ul_default_ws+1);
}

static void run_flash_information_test()
{
	uint32_t ul_flash_descriptor[8];
	uint32_t ul_page_count;
	uint32_t ul_page_count_per_region;
	uint32_t ul_region_count;

	/* Get the flash descriptor */
	flash_get_descriptor(IFLASH_ADDR, ul_flash_descriptor, 8);

	ul_page_count = flash_get_page_count(ul_flash_descriptor);

	/* Validate the get page count function */
	debug_print("Test flash information:get page count:%d\r\n",ul_page_count);

	/* Read the page count number in one region */
	ul_page_count_per_region = flash_get_page_count_per_region(ul_flash_descriptor);

	/* Validate the get page count per region function */
	debug_print("Test flash information:get page count per region:%d\r\n",ul_page_count_per_region);

	/* Get the region number */
	ul_region_count = flash_get_region_count(ul_flash_descriptor);

	/* Validate the get region count function */
	debug_print("Test flash information:get region count:%d\r\n",ul_region_count);
}

static void run_flash_lock_test()
{
	volatile uint32_t ul_locked_region_num;
	volatile uint32_t lockerror = 0;
	uint32_t ul_test_page_addr = TEST_PAGE_ADDRESS;
	
#if (SAM4S || SAM4E || SAM4N || SAM4C || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAMS70 || SAME70)
	flash_erase_sector(ul_test_page_addr);
#endif
	uint32_t ul_page_buffer[IFLASH_PAGE_SIZE / sizeof(uint32_t)];
	memset((void *)ul_page_buffer, 0xFF, IFLASH_PAGE_SIZE);


	/* Check if there is any region blocked */
	ul_locked_region_num = flash_is_locked(IFLASH_ADDR,ul_test_page_addr + IFLASH_PAGE_SIZE - 1);

	/* If all the regions are unlocked, set the test page locked */
	if (ul_locked_region_num == 0) {
		/* Lock the test page */
		flash_lock(ul_test_page_addr,ul_test_page_addr + IFLASH_PAGE_SIZE - 1, 0, 0);
	}

	/* Unlock the test page region */
	flash_unlock(IFLASH_ADDR, ul_test_page_addr + IFLASH_PAGE_SIZE - 1, 0, 0);

	/* Check if there is any region blocked */
	ul_locked_region_num = flash_is_locked(IFLASH_ADDR,	ul_test_page_addr + IFLASH_PAGE_SIZE - 1);

	/* Validate the the unlock function */
	debug_print("Test flash lock: flash unlock:%d\r\n",ul_locked_region_num);

	/* Lock the test page region */
	flash_lock(ul_test_page_addr,ul_test_page_addr + IFLASH_PAGE_SIZE - 1, 0, 0);

	lockerror = flash_write(ul_test_page_addr, (void *)ul_page_buffer,IFLASH_PAGE_SIZE, 0);

#if (SAM3SD8 || SAM4S || SAM4E || SAM4N || SAM4C || SAM4CP || SAM4CM || \
	 SAMV71 || SAMV70 || SAMS70 || SAME70)
	/* SAM3SD8, SAM4S, SAM4E, SAM4N, SAM4C, SAM4CP, SAMV71, SAMV70, SAMS70,
	 * and SAME70 have a bigger page region which requires special attention.
	 */
	ul_locked_region_num = flash_is_locked(IFLASH_ADDR,	ul_test_page_addr + IFLASH_PAGE_SIZE - 1);
#else
	ul_locked_region_num = flash_is_locked(ul_test_page_addr,ul_test_page_addr + IFLASH_PAGE_SIZE - 1);
#endif

	/* Unlock the test page region */
	flash_unlock(IFLASH_ADDR, ul_test_page_addr + IFLASH_PAGE_SIZE - 1, 0, 0);

	/* Validate the lock function */
	debug_print("Test flash lock: flash lock:%d\r\n",ul_locked_region_num);
	//debug_print("Test flash lock: expect a flash lock error:%d\r\n",lockerror);
}

static void run_flash_write_test()
{
	uint32_t ul_page_buffer[IFLASH_PAGE_SIZE / sizeof(uint32_t)];
	uint32_t ul_rc=0;
	uint32_t ul_idx;
	uint32_t ul_test_page_addr = TEST_PAGE_ADDRESS;
	uint32_t *pul_test_page = (uint32_t *) ul_test_page_addr;

	/* Unlock the whole flash */
	flash_unlock(IFLASH_ADDR,  ul_test_page_addr + IFLASH_PAGE_SIZE - 1, 0, 0);

	/* Write the test page with walking bit pattern */
	for (ul_idx = 0; ul_idx < (IFLASH_PAGE_SIZE / 4); ul_idx++) {
		ul_page_buffer[ul_idx] = 1 << (ul_idx % 32);
	}

	#if (SAM4S || SAM4E || SAM4N || SAM4C || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAMS70 || SAME70)
	   /* Write the test page */
	   flash_erase_sector(ul_test_page_addr);
	   flash_write(ul_test_page_addr,(void *)ul_page_buffer,IFLASH_PAGE_SIZE, 0);
	#else
	   flash_write(ul_test_page_addr,(void *)ul_page_buffer,IFLASH_PAGE_SIZE, 1);
	#endif

	/* Validate page contents */
	for (ul_idx = 0; ul_idx < (IFLASH_PAGE_SIZE / 4); ul_idx++) {
		if (pul_test_page[ul_idx] != ul_page_buffer[ul_idx]) {
			ul_rc =1;
		}
	}

	/* Validate the flash write function */
	debug_print("Test flash write: flash write:%d\r\n",ul_rc);
}

static void run_flash_gpnvm_test()
{
	uint32_t ul_rc;

	/* Get the default gpnvm 1 status */
	ul_rc = flash_is_gpnvm_set(1);

	/* Reverse the test, clear/set  the gpnvm */
	if (ul_rc == FLASH_RC_YES) {  /* default gpnvm 1 is set */
		/* Clear the gpnvm 1 */
		flash_clear_gpnvm(1);

		/* Get the gpnvm 1 status */
		ul_rc = flash_is_gpnvm_set(1);

		/* Validate the gpnvm clear interface */
		debug_print("Test flash GPNVM: flash GPNVM clear:%d\r\n",ul_rc);
		} else {
		/* Set the gpnvm 1 */
		flash_set_gpnvm(1);

		ul_rc = flash_is_gpnvm_set(1);

		/* Validate the gpnvm set interface */
		debug_print("Test flash GPNVM: flash GPNVM set:%d\r\n",ul_rc);
	}

	/* Reverse the test, set/clear the gpnvm */
	if (ul_rc == FLASH_RC_YES) {
		/* Clear the gpnvm 1 */
		flash_clear_gpnvm(1);

		/* Get the gpnvm 1 status */
		ul_rc = flash_is_gpnvm_set(1);

		/* Validate the gpnvm clear interface */
		debug_print("Test flash GPNVM: flash GPNVM clear:%d\r\n",ul_rc);
		} else {
		/* Set the gpnvm 1 */
		flash_set_gpnvm(1);

		/* Get the gpnvm 1 status */
		ul_rc = flash_is_gpnvm_set(1);

		/* Validate the gpnvm set interface */
		debug_print("Test flash GPNVM: flash GPNVM set:%d\r\n",ul_rc);
	}
}
